import Handler from "./Handler";

export default class Messenger {

    private cmdHandlers = {};
    private cmdInterceptors: Handler[] = [];

    public sendMessage(message: string, args: any[]=[]) {
        const coms = this.cmdHandlers[message] as any[];
        if (!coms || coms.length <= 0) {
            console.warn(`没有找到注册此消息的组件:${message}, 请检查消息是否拼写错误`);
            return;
        } else {
            // 检测是否有拦截组件将消息处理了.
            for (const interceptor of this.cmdInterceptors) {
                if (interceptor.handleMessage(message, args)) {
                    return;
                }
            }

            let ret = false;
            for (const com of coms) {
                ret = com.handleMessage(message, args);
                if (ret) {
                    cc.log(`消息:${message},被组件 ${coms} 拦截,不再向下传递.`);
                    break;
                }
            }
        }
    }

    // 将某些消息注册在某组件上.当有人发送此消息时,组件将被通知.
    public register(com: Handler, messages: string[]) {

        for (const message of messages) {
            let coms = this.cmdHandlers[message] as Handler[];
            if (!coms) {
                coms = [];
                coms.push(com);
                this.cmdHandlers[message] = coms;
            } else {
                const index = coms.indexOf(com);
                if (index == -1) {
                    coms.push(com);
                }
            }
        }
    }

    // 从组件上删除某些已注册的消息.
    public unregister(com: Handler, message: string[]) {
        if (!message) {
            for (const key in this.cmdHandlers) {
                if (this.cmdHandlers.hasOwnProperty(key)) {
                    const coms = this.cmdHandlers[key] as Handler[];
                    if (!coms || coms.length <= 0) {
                        continue;
                    }
                    const index = coms.indexOf(com);
                    if (index == -1) {
                        return;
                    }
                    coms.splice(index, 1);
                }
            }
            return;
        }
        for (const msg of message) {
            const coms = this.cmdHandlers[msg] as Handler[];
            if (!coms || coms.length <= 0) {
                continue;
            }
            const index = coms.indexOf(com);
            if (index == -1) {
                return;
            }
            coms.splice(index, 1);
        }
    }

    public addInterceptor(com: Handler) {
        if (this.cmdInterceptors.indexOf(com) != -1) {
            return;
        }
        this.cmdInterceptors.push(com);
    }
}
